package org.finesys.common.core.interceptor;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;

import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.lang.NonNull;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

/**
 * restClient 日志拦截器
 */
@Slf4j
public class RestLoggingInterceptor implements ClientHttpRequestInterceptor {
    @Override
    @NonNull
    public ClientHttpResponse intercept(@NonNull HttpRequest request,@NonNull byte[] body,@NonNull ClientHttpRequestExecution execution) throws IOException {
        traceRequest(request, body);
        long start = System.currentTimeMillis();
        ClientHttpResponse clientHttpResponse = execution.execute(request, body);
        long end = System.currentTimeMillis();
        traceResponse(request, body, clientHttpResponse, start, end);
        return clientHttpResponse;
    }

    /**
     * 打印请求头信息
     */
    private void traceRequest(HttpRequest request, byte[] body) {
        StringBuilder sb = new StringBuilder();
        sb.append("\n==============request begin=========\n");
        sb.append("URI         :").append(request.getURI()).append("\n");
        sb.append("Method      :").append(request.getMethod()).append("\n");
        sb.append("Headers     :").append(request.getHeaders()).append("\n");
        sb.append("Request Body:").append(new String(body, StandardCharsets.UTF_8)).append("\n");
        sb.append("\n==============request end=========\n");
        if (log.isDebugEnabled()) {
            log.debug(sb.toString());
        }
    }

    /**
     * 打印响应头信息
     */
    @SneakyThrows
    private void traceResponse(HttpRequest request, byte[] body, ClientHttpResponse clientHttpResponse, long start, long end) {

        //返回结果信息
        StringBuilder responseStr = new StringBuilder();
        try {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(clientHttpResponse.getBody(), StandardCharsets.UTF_8));
            String line = bufferedReader.readLine();
            while (line != null) {
                responseStr.append(line);
                line = bufferedReader.readLine();
            }
        } catch (IOException e) {
        }
        //打印信息
        StringBuilder sb = new StringBuilder();
        sb.append("\n==============response begin=========\n");
        sb.append("URI          :").append(request.getURI()).append("\n");
        sb.append("Method       :").append(request.getMethod()).append("\n");
        sb.append("Headers      :").append(request.getHeaders()).append("\n");
        sb.append("Request  Body:").append(new String(body, StandardCharsets.UTF_8)).append("\n");
        sb.append("Response Body:").append(responseStr).append("\n");
        sb.append("TIME         :").append(request.getURI()).append("\n");
        sb.append("Status   Code:").append(clientHttpResponse.getStatusCode()).append("\n");
        sb.append("\n==============response end=========\n");
        if (clientHttpResponse.getStatusCode().is2xxSuccessful()) {
            if (log.isDebugEnabled()) {
                log.debug(sb.toString());
            }
        } else {
            if (log.isErrorEnabled()) {
                log.error(sb.toString());
            }
        }
    }
}
